import { type FunctionalComponent, type VNode, computed, defineComponent } from 'vue'
import { Input, InputNumber, Slider, Radio, Select } from 'ant-design-vue'
import { reduce } from 'lodash-es'
import { mapPropsToForms } from '@/mock/mapPropsToForms'
import type { TextComponentProps } from '@/types/defaultProps'

const mapToComponent = {
  'a-textarea': Input.TextArea,
  'a-input-number': InputNumber,
  'a-slider': Slider,
  'a-radio-group': Radio.Group,
  'a-radio-button': Radio.Button,
  'a-select': Select,
  'a-select-option': Select.Option
} as any
const capitalizeFirstLetter = (string: string) => {
  return string.charAt(0).toUpperCase() + string.slice(1)
}
interface FormProps {
  component: string
  subComponent?: string
  value: string
  extraProps?: { [key: string]: any }
  text?: string
  options?: { text: string | VNode; value: any }[]
  valueProp: string
  eventName: string
  events: { [key: string]: (e: any) => void }
}

const PropsTable: FunctionalComponent<any> = (props, { slots, emit, attrs }) => {
  const finalProps = computed(() => {
    return reduce(
      props.props,
      (result, value, key) => {
        const newKey = key as keyof TextComponentProps // 断言
        const item = mapPropsToForms[newKey]
        if (item) {
          const {
            valueProp = 'value',
            eventName = 'change',
            initalTransform,
            afterTransform
          } = item
          const newItem: FormProps = {
            ...item,
            value: initalTransform ? initalTransform(value) : value,
            valueProp,
            eventName,
            events: {
              ['on' + capitalizeFirstLetter(eventName)]: (e: any) => {
                emit('change', {
                  key,
                  value: afterTransform ? afterTransform(e) : e
                })
              }
            }
          }
          // item.value = item.initalTransform ? item.initalTransform(value) : value
          // item.valueProp = item.valueProp ? item.valueProp : 'value'
          result[newKey] = newItem
        }
        return result
      },
      // {} as Required<PropsToForms>
      // {} as PropsToForms
      {} as { [key: string]: FormProps }
    )
  })
  return (
    <div class="props-table">
      {Object.keys(finalProps.value).map((key) => {
        const value = finalProps.value[key]
        const ComponentName = mapToComponent[value.component]
        const SubComponent = value.subComponent ? mapToComponent[value.subComponent] : null
        const props = {
          [value.valueProp]: value.value,
          ...value.extraProps,
          ...value.events
        }
        return (
          <div key={key} class="prop-item">
            {value.text && <span class="label">{value.text}</span>}
            <div class="prop-component">
              <ComponentName {...props}>
                {value.options &&
                  value.options.map((option) => {
                    return <SubComponent value={option.value}>{option.text}</SubComponent>
                  })}
              </ComponentName>
            </div>
          </div>
        )
      })}
    </div>
  )
}

export default PropsTable
